<?php


namespace App\Http\Utils;


use Swoole\Coroutine\Http\Client;
use Swoole\Exception;

class DianxingApi
{
    /**
     * @param $deviceid string 设备id
     * @return array
     * @throws Exception
     */
    public static function delDevice($deviceid): array
    {

        //检查配置
        if(is_null(\config("dianxin") == "") || !isset(\config("dianxin")["appId"]) || !isset(\config("dianxin")["secret"]) )
        {
            throw new Exception("请检查配置文件 dianxin.php");
        }

        $req_array = array();
        $req_array["uir"] = "/iocm/app/dm/v1.4.0/devices/".$deviceid."?appId=".\config("dianxin")["appId"];
        $req_array["header"] = [
            "Content-Type"=>"application/json",
            "Authorization"=>"Bearer ".DianxingApi::getAccessToken(),
            "app_key"=> \config("dianxin")["appId"],
        ];

        return DianxingApi::response_del($req_array);

    }
    /**
     * @param $imei string
     * @param $isSecure bool 是否加密
     * @return array
     * @throws Exception
     */
    public static function addDevice($imei,$isSecure): array
    {


        //检查配置
        if(is_null(\config("dianxin") == "") || !isset(\config("dianxin")["appId"]) || !isset(\config("dianxin")["secret"]) )
        {
            throw new Exception("请检查配置文件 dianxin.php");
        }

        $req_array = array();
        $req_array["uir"] = "/iocm/app/reg/v1.1.0/deviceCredentials?appId=".\config("dianxin")["appId"];
        $req_array["header"] = [
            "Content-Type"=>"application/json",
            "Authorization"=>"Bearer ".DianxingApi::getAccessToken(),
            "app_key"=> \config("dianxin")["appId"],
        ];
        $req_array["data"] = json_encode([
            "isSecure"=>$isSecure,
            "nodeId"=>$imei,
            "verifyCode"=>$imei,
            "deviceInfo"=>[
                "manufacturerName" => "SSZL",
                "manufacturerId" => "908a9ddb86c44803b94a4e9be8e33269",
                "deviceType" => "DataUp",
                "model" => "SSZL_SY_0001",
                "protocolType" => "LWM2M",
            ]
        ]);
        return DianxingApi::response($req_array);



    }
    /**
     * @param $deviceid string //设备id
     * @param $cmd string //命令
     * @param $uir //回调链接
     * @return array|string|null
     * @throws Exception
     */
    public static function deviceCommands($deviceid,$cmd,$uir)
    {

        //检查配置
        if(is_null(\config("dianxin") == "") || !isset(\config("dianxin")["appId"]) || !isset(\config("dianxin")["secret"]) )
        {
            throw new Exception("请检查配置文件 dianxin.php");
        }


        $req_array = array();
        $req_array["uir"] = "/iocm/app/cmd/v1.4.0/deviceCommands?appId=".\config("dianxin")["appId"];
        $req_array["header"] = [
            "Content-Type"=>"application/json",
            "Authorization"=>"Bearer ".DianxingApi::getAccessToken(),
            "app_key"=> \config("dianxin")["appId"],
        ];
        $cmd_data  = null;
        if(is_array($cmd))
            $cmd_data = json_encode($cmd);
        else
            $cmd_data = $cmd;

        $req_array["data"] = (json_encode([
            "deviceId"=>$deviceid,
            "command"=>[
                "serviceId" => "cmd",
                "method" => "cmd",
                "paras" => [
                    "json_cmd"=>$cmd_data
                ]
            ],
            "callbackUrl"=>$uir,
        ]));

        return DianxingApi::response($req_array);
    }



    /**
     * 获取电信平台AccessToken 自动更新请求
     * @return string|null
     * @throws Exception
     */
    private static function getAccessToken()
    {

        //检查配置

        if(is_null(\config("dianxin") == "") || !isset(\config("dianxin")["appId"]) ||!isset(\config("dianxin")["secret"]) )
        {
            throw new Exception("请检查配置文件 dianxin.php");
        }

        if(!file_exists(__DIR__."/DianXinApi_CA/dianxin_accessTokenFile.json"))
        {
            goto request_accessToken;
        }
        $accessTokenJson  = file_get_contents(__DIR__."/DianXinApi_CA/dianxin_accessTokenFile.json");

        if($accessTokenJson == "")
        {
            goto request_accessToken;
        }
        $accessToken = json_decode($accessTokenJson,true);
        if(isset($accessToken['accessToken']) || isset($accessToken['accessTokenOutTime']) || isset($accessToken['refreshToken']))
        {
            goto request_accessToken;
        }
        $newdate = time();
        $req_array = array();
        if($newdate >  $accessToken['accessTokenOutTime'] )//请求$accessToken
        {
            request_accessToken:
            $req_array["uir"] = "/iocm/app/sec/v1.1.0/login";
            $req_array["data"] = array("appId" => \config("dianxin")["appId"],"secret"=>\config("dianxin")["secret"]);
            $req_array["header"] = ["Content-Type"=>"application/x-www-form-urlencoded"];
        }
        else if($newdate - \config("dianxin",["remaining_time" => 60])["remaining_time"] > $accessToken['accessTokenOutTime'])//刷新
        {
            $req_array["uir"] = "/iocm/app/sec/v1.1.0/refreshToken";
            $req_array["data"] = array("appId" => \config("dianxin")["appId"],"secret"=>\config("dianxin")["secret"],"refreshToken"=>$accessToken["refreshToken"]);
            $req_array["header"] = ["Content-Type"=>"application/x-www-form-urlencoded"];
        }
        if(isset($req_array['uir']) && isset($req_array['data']))
        {


            $res = DianxingApi::response($req_array);

            if(isset($res['error_code']))
            {
                throw new Exception("请求".$req_array['uir']."出错！请检查配置文件 dianxin.php");
            }
            if(isset($res['accessToken']))
            {
                $accessToken['accessToken'] = $res['accessToken'];
            }
            if(isset($res["expiresIn"]))
            {
                $accessToken['accessTokenOutTime'] = time()  + $res['expiresIn'];
            }
            if(isset($res['refreshToken']))
            {
                $accessToken['refreshToken'] = $res['refreshToken'];
            }

            file_put_contents(__DIR__."/DianXinApi_CA/dianxin_accessTokenFile.json",json_encode($accessToken));
        }


        return $accessToken['accessToken'];

    }
    /**
     * 请求电信平台
     * @param $req_array
     * @return array|null
     * @throws Exception
     */
    private static function response($req_array)
    {
        if(!isset($req_array['uir']))
            return null;
        $cli = new Client('180.101.147.89', 8743, true);

        $cli->set(array(
            'ssl_cert_file' => __DIR__ . '/DianXinApi_CA/server.crt',
            'ssl_key_file' => __DIR__ . '/DianXinApi_CA/server.key',
        ));
        if(isset($req_array["header"]))
            $cli->setHeaders($req_array["header"]);
        $data = null;
        if(isset($req_array["data"])) {
            if(is_array($req_array["data"]))
                $data = json_encode($req_array["data"]);
            else
                $data = $req_array["data"];
        }

        if(!$cli->post($req_array['uir'],$data))
        {
            throw new Exception("请求失败");
        }
//        if($cli->getStatusCode() < 200 | $cli->getStatusCode() >= 300)
//            throw new Exception("电信平台请求错误 错误码:".$cli->getStatusCode() ."\r\n".$cli->getBody());
        $rec = json_decode($cli->getBody(),true);
        $rec["StatusCode"] = $cli->getStatusCode();//添加状态码
        $cli->close();
        return $rec;
    }
    /**
     * 请求电信平台
     * @param $req_array
     * @return array|null
     * @throws Exception
     */
    private static function response_del($req_array)
    {
        if(!isset($req_array['uir']))
            return null;
        $cli = new Client('180.101.147.89', 8743, true);

        $cli->set(array(
            'ssl_cert_file' => __DIR__ . '/DianXinApi_CA/server.crt',
            'ssl_key_file' => __DIR__ . '/DianXinApi_CA/server.key',
        ));
        if(isset($req_array["header"]))
            $cli->setHeaders($req_array["header"]);
        $data = null;
        if(isset($req_array["data"])) {
            if(is_array($req_array["data"]))
                $data = $req_array["data"];
            else
                $data = stripslashes($req_array["data"]);
        }
        $cli->setData($data);
        $cli->setMethod("DELETE");

        if(!$cli->execute($req_array['uir']))
        {
            throw new Exception("请求失败");
        }
//        if($cli->getStatusCode() < 200 | $cli->getStatusCode() >= 300)
//            throw new Exception("电信平台请求错误 错误码:".$cli->getStatusCode() ."\r\n".$cli->getBody());
        $rec = json_decode($cli->getBody(),true);
        $rec["StatusCode"] = $cli->getStatusCode();//添加状态码
        $cli->close();
        return $rec;
    }
    /**
     * @param $req_array
     * @return mixed|null
     * @throws Exception
     */
    private static function response2($req_array)
    {
        if(!isset($req_array['uir']))
            return null;
        $cli = new Client('swoft.sszlbg.cn', 443, true);

        $cli->set(array(
            'ssl_cert_file' => __DIR__ . '/DianXinApi_CA/server.crt',
            'ssl_key_file' => __DIR__ . '/DianXinApi_CA/server.key',
        ));
        if(isset($req_array["header"]))
            $cli->setHeaders($req_array["header"]);
        $data = null;
        if(isset($req_array["data"])) {
            if(is_array($req_array["data"]))
                $data = $req_array["data"];
            else
                $data = stripslashes($req_array["data"]);
        }
        if(!$cli->post("/v1/deviceCommandsReply",$data))
        {
            throw new Exception("请求失败");
        }
        $rec = $cli->getBody();

        $cli->close();
        return $rec;
    }
}
